package com.ddpt.permission.util;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.lh.center.common.exception.CommonException;
import com.lh.center.common.exception.ErrorEnum;
import com.lh.center.extensions.api.utils.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.net.ssl.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.UUID;

// 国泰相关接口请求
@Slf4j
@Component
public class GtHttpUtil {

    // 国泰消保客户请求接口相关参数定义
    @Value("${gt.url:https://testbp.cathaylife.cn/gateway/openapi/customer/activity}")
    private String url;
    @Value("${gt.keyStorePath:./jwt/keystore.jks}")
    private String keyStorePath;
    @Value("${gt.alias:testbp.cathaylife.cn}")
    private String alias;
    @Value("${gt.password:cathaylife}")
    private String password;
    @Value("${gt.copId:LIANHAI}")
    private String copId;

    // 通过手机号调用国泰接口，获取国泰用户信息
    public String getCustomer(String uid, String phone) {

        JSONObject obj = JSONUtil.createObj();
        obj.set("wechatUid", uid); // 微信号
        obj.set("mobile", phone); // 手机号
        String sub = MD5Util.getMD5String(obj.toString());
        JWTJKSUtil util = JWTJKSUtil.getInstance(alias, password, keyStorePath);
        String jwtToken = util.generateJWTToken(null, sub, null, null, null);

        log.info("调用国泰客户信息接口请求链接-{}, sub--{}, token--{}, 参数:{}", url, sub, jwtToken, obj);

        /*HttpRequest request = HttpRequest.post(url);
        request.header("msgId", msgId);
        request.header("copId", copId); // 合作单位代号
        request.header("jwtToken", jwtToken);
        request.setSSLSocketFactory(getSocketFactory());
        request.body(obj.toString());
        HttpResponse res = request.execute();*/

        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("msgId", UUID.randomUUID().toString().replace("-", ""));
        httpPost.addHeader("copId", copId); // 合作单位代号
        httpPost.addHeader("jwtToken", jwtToken);
        httpPost.addHeader("Content-type", "application/json;charset=utf-8");
        httpPost.setEntity(new StringEntity(obj.toString(), StandardCharsets.UTF_8));
        // httpPost.setConfig(RequestConfig.custom().setConnectTimeout(10000).build());
        CloseableHttpClient httpClient = createSSLClientDefault();
        try {
            CloseableHttpResponse res = httpClient.execute(httpPost);
            if (null == res) {
                throw new CommonException("国泰客户信息接口返回数据为空");
            }
            log.info("国泰客户信息接口返回：{}", res);
            return EntityUtils.toString(res.getEntity(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            log.error("请求国泰接口异常", e);
            e.printStackTrace();
            throw new CommonException(ErrorEnum.error, e, "调用国泰客户查询接口异常");
        }finally {
            try {
                // httpResponse.close();
                if (null != httpClient){
                    httpClient.close();
                    log.info("请求流关闭完成");
                }
            } catch (IOException e) {
                log.error("请求流关闭出错", e);
            }
        }
    }

    public static CloseableHttpClient createSSLClientDefault() {
        try {
            // 信任所有
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();

    }

    private static SSLSocketFactory getSocketFactory() {
        // https 请求设置证书认证
        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{
                    new X509TrustManager() {
                        //检查客户端证书，若不信任该证书抛出异常，咱们自己就是客户端不用检查
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) {
                        }

                        //检查服务器的证书，若不信任该证书抛出异常，可以不检查默认都信任
                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) {
                        }

                        //返回受信任的X509证书数组
                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[]{};
                        }
                    }
            }, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

